#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <errno.h>
#include <elog.h>
#include <utils/timerfunc.hpp>
#include <sys/time.h>
#include <string.h>
#include <autoinit.hpp>

// UTF-8


/*----Private functions---------------------------------------------------------*/
/**
 * @brief  创建定时器
 * @param  timer_callback my_func:定时器到期时调用的回调函数
 *         void *my_param        :回调函数的入参
 *         timer_t *pxTimer      :存放定时器ID的结构体地址
 * @return 0表示创建成功, 创建的定时器的ID存放在pxTimer中
 *         -1表示失败,失败原因查看errno
 * @note
 * @author hwx
 * @date   2019/12/23
 */
static int timer_init(timer_callback my_func, void *my_param, timer_t *pxTimer)
{
	struct sigevent evp;

	/*采用新线程派驻的方式*/
	memset(&evp, 0x00, sizeof(evp));
	evp.sigev_value.sival_ptr = &pxTimer;
	evp.sigev_notify = SIGEV_THREAD;
	evp._sigev_un._sigev_thread._function = my_func;
	evp.sigev_value.sival_int = reinterpret_cast<int>(my_param);

	int ret = timer_create(CLOCK_REALTIME, &evp, pxTimer);
	if(ret != 0)
	{
		log_e("timer_create error: %d\n", errno);
        return ret;
	}

//	LOGI("init timer success, timeout[ %d ]s\n", timeout_seconds);
    return ret;
}


/**
 * @brief  设置并启用定时器
 * @param  timer_t timer     :需要启用的定时器的ID
 *         int millisecond   :期望到期时间毫秒数
 *         bool interval_flag:0-单次定时器; 1-循环定时器
 * @return 0表示启用成功
 *         -1表示失败,失败原因查看errno
 * @note   若对同一 TIMER 多次进行此操作,则 TIMER 以最后一次操作设置的时间执行
 * @author hwx
 * @date   2019/12/13
 */
static int timer_set_up(timer_t timer, int millisecond, bool interval_flag)
{
	struct itimerspec ts;
	if(millisecond < 1000)
	{
		int nsec_value = millisecond * 1000000; //ms ==> ns
		ts.it_interval.tv_sec = 0;
		ts.it_interval.tv_nsec = interval_flag ? nsec_value : 0;
		ts.it_value.tv_sec = 0;
		ts.it_value.tv_nsec = nsec_value;   //it_value.tv_nsec不能大于999999999
	}
	else
	{
		int sec_value = millisecond / 1000;	//ms ==> s
        int nsec_value = (millisecond % 1000) * 1000000;    //ns
		ts.it_interval.tv_sec = interval_flag ? sec_value : 0;
		ts.it_interval.tv_nsec = interval_flag ? nsec_value : 0;
		ts.it_value.tv_sec = sec_value;
		ts.it_value.tv_nsec = nsec_value;
	}

	int ret = timer_settime(timer, 0, &ts, NULL);
	if(ret != 0)
	{
		log_e("timer_settime error: %d\n", errno);
        return ret;
	}

//	LOGI("setup timer success, timeout[ %d ]s\n", timeout_seconds);
    return ret;
}

/**
 * @brief  暂停定时器(非删除)
 * @param  timer_t timer      :需要暂停的定时器的ID
 * @return 0表示暂停成功
 *         -1表示失败,失败原因查看errno
 * @note
 * @author hwx
 * @date   2019/12/23
 */
static int timer_stop(timer_t timer)
{
	struct itimerspec ts;
	memset(&ts, 0x00, sizeof(ts));

	int ret = timer_settime(timer, 0, &ts, NULL);
	if(ret != 0)
	{
		log_e("timer_settime error: %d\n", errno);
        return ret;
	}
//	LOGI("stop timer success, timeout[ %d ]s\n", timeout_seconds);
    return ret;
}

/**
 * @brief  删除定时器
 * @param  timer_t timer:需要删除的定时器的ID
 * @return 0表示设置成功
 *         -1表示失败,失败原因查看errno
 * @note
 * @author hwx
 * @date   2019/12/13
 */
static int timer_tear_down(timer_t timer)
{
    int ret = 0;

	ret = timer_delete(timer);
	if(ret != 0)
	{
		log_e("timer_delete error: %d\n", errno);
		return ret;
	}
	else
	{
//		LOGI("delete timer success\n");
	}

    return ret;
}

static struct timing_manager this_obj = {
	.init     = timer_init,
	.setUp    = timer_set_up,
	.stop     = timer_stop,
	.tearDown = timer_tear_down,
};


struct timing_manager* get_timing(void)
{
    return &this_obj;
}


// test
void timer1_callback(sigval_t param) 
{
	log_i("******* timer1_callback! \n");

	return;
}

void timer_test(void)
{
	timer_t Timer1;

	memset(&Timer1, 0, sizeof(timer_t));
	get_timing()->init(timer1_callback, NULL, &Timer1);
	int msecond = 5000; // 毫秒
	get_timing()->setUp(Timer1, msecond, false); // false = do once
}

//auto_dev_init(timer_test);

